package org.example.maven.service.Impl;

import com.google.common.collect.Lists;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.example.maven.pojo.list.ListTableCollectionAddDetail;
import org.example.maven.service.ExcelImportService;
import org.example.maven.utils.excel.ExcelImportResult;
import org.example.maven.utils.excel.ExcelRowParser;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.apache.poi.ss.usermodel.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Service
public class ExcelImportServiceImpl implements ExcelImportService {
    // 新增线程池定义
    private static final ExecutorService uploadExecutor =
            Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
    @Override
    public <T> ExcelImportResult<T> importExcel(MultipartFile file, ExcelRowParser<T> parser, int batchSize, Consumer<List<T>> batchConsumer) throws IOException {
        ExcelImportResult<T> result = new ExcelImportResult<>();
        List<CompletableFuture<T>> allFutures = new ArrayList<>();

        try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
            Sheet sheet = workbook.getSheetAt(0);

            for (Row row : sheet) {
                int rowNum = row.getRowNum();
                result.setTotalRows(result.getTotalRows() + 1);

                CompletableFuture<T> future = CompletableFuture.supplyAsync(() -> {
                    try {
                        if (parser.shouldSkip(row, rowNum)) return null;
                        return parser.parse(row, rowNum);
                    } catch (Exception e) {
                        result.getErrors().add(new ExcelImportResult.RowError(rowNum+1, e.getMessage()));
                        return null;
                    }
                }, uploadExecutor); // 使用上传线程池
                allFutures.add(future);
            }

            // 第二阶段：统一处理结果
            CompletableFuture<Void> allDone = CompletableFuture.allOf(allFutures.toArray(new CompletableFuture[0]));

            // 修改结果处理部分
            List<T> successData = allDone.thenApply(v ->
                    allFutures.stream()
                            .filter(f -> !f.isCompletedExceptionally())
                            .map(f -> {
                                try {
                                    return f.get(); // 显式获取结果触发异常检查
                                } catch (Exception e) {
                                    return null;
                                }
                            })
                            .filter(Objects::nonNull)
                            .collect(Collectors.toList())
            ).join();
            // 新增：等待所有图片上传完成
            successData.forEach(item -> {
                if (item instanceof ListTableCollectionAddDetail) {
                    ListTableCollectionAddDetail detail = (ListTableCollectionAddDetail) item;
                    try {
                        if (detail.getImgFuture() != null) {
                            detail.getImgFuture().get(); // 阻塞直到上传完成
                        }
                    } catch (Exception e) {
                        // 记录上传失败
                    }
                }
            });

            result.getSuccessData().addAll(successData);
            result.setSuccessCount(successData.size());

            // 批量消费（如果需要）
            if (batchConsumer != null) {
                Lists.partition(successData, batchSize).forEach(batchConsumer);
            }
        }
        return result;
    }
}
